---
title: Full Example - Vue & Vuetify PDF Viewer
description: Explore a complete, production-ready PDF viewer built with EmbedPDF, Vue, and Vuetify 3. 
searchable: true
---

import { Callout } from '@/components/callout'

# Full Example: Vue & Vuetify PDF Viewer

While the previous guides show how to use individual plugins, it's often helpful to see how they all come together in a complete application. This page showcases a feature-rich, responsive PDF viewer built with EmbedPDF, **Vue 3**, and the **Vuetify 3** component framework.

This example serves as a practical blueprint, demonstrating how to build a polished and cohesive user experience by combining EmbedPDF's headless components with a popular UI library.

  - **Live Demo:** [**vuetify.embedpdf.com**](https://vuetify.embedpdf.com/)
  - **Source Code:** [**View on GitHub**](https://github.com/embedpdf/embed-pdf-viewer/tree/main/examples/vue-vuetify)

<Callout type="info">
This example is a great starting point for your own project. Feel free to fork the repository and adapt the code to fit your needs.
</Callout>

## Features Showcase

The Vuetify example integrates numerous plugins to create a comprehensive viewing experience.

| Feature                                                    | Plugin(s) Used                                                                    |
| ---------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Virtualized scrolling with smooth page rendering           | `@embedpdf/plugin-scroll` + `@embedpdf/plugin-render` + `@embedpdf/plugin-tiling` |
| Advanced zoom controls (presets, fit-to-page, marquee)     | `@embedpdf/plugin-zoom`                                                           |
| Pan/hand tool for easy navigation                          | `@embedpdf/plugin-pan`                                                            |
| Page rotation in 90-degree increments                      | `@embedpdf/plugin-rotate`                                                         |
| Single and two-page spread layouts                         | `@embedpdf/plugin-spread`                                                         |
| Thumbnail sidebar for quick page jumping                   | `@embedpdf/plugin-thumbnail`                                                      |
| In-document text search with result highlighting           | `@embedpdf/plugin-search`                                                         |
| File opening, downloading, and printing                    | `@embedpdf/plugin-loader`, `@embedpdf/plugin-export`, `@embedpdf/plugin-print`    |
| Fullscreen mode                                            | `@embedpdf/plugin-fullscreen`                                                     |
| Text selection and copy-to-clipboard                       | `@embedpdf/plugin-selection`                                                      |
| Annotations (ink, shapes, text, stamps)                    | `@embedpdf/plugin-annotation`                                                     |
| Text and area redaction                                    | `@embedpdf/plugin-redaction`                                                      |

## Core Concepts Illustrated

### 1\. Centralized Plugin Registration

All features are enabled and configured in a single `plugins` array within the main `Application.vue` component. This makes it easy to see what capabilities the viewer has and to add or remove features.

```vue filename="src/components/Application.vue"
<script setup lang="ts">
// ...
const plugins = [
  createPluginRegistration(LoaderPluginPackage, { /* ... */ }),
  createPluginRegistration(ViewportPluginPackage, { /* ... */ }),
  createPluginRegistration(ScrollPluginPackage, { /* ... */ }),
  createPluginRegistration(RenderPluginPackage),
  createPluginRegistration(TilingPluginPackage, { /* ... */ }),
  createPluginRegistration(ZoomPluginPackage, { /* ... */ }),
  createPluginRegistration(SearchPluginPackage),
  createPluginRegistration(InteractionManagerPluginPackage),
  createPluginRegistration(PanPluginPackage),
  createPluginRegistration(RotatePluginPackage),
  createPluginRegistration(SpreadPluginPackage),
  createPluginRegistration(FullscreenPluginPackage),
  createPluginRegistration(ExportPluginPackage),
  createPluginRegistration(ThumbnailPluginPackage),
  createPluginRegistration(SelectionPluginPackage),
  // ... and more
];
</script>
```

### 2\. Composable UI Components

The UI is broken down into logical, reusable Single File Components, each leveraging Vuetify's component library (e.g., `<Toolbar.vue>`, `<Sidebar.vue>`, `<Search.vue>`). Each component is responsible for a specific piece of the UI and uses EmbedPDF composables to interact with the relevant plugins.

For example, the `<ZoomControls.vue>` component uses the `useZoom` composable to manage zoom functionality through `VBtn` and `VMenu`.

```vue filename="src/components/ZoomControls.vue"
<script setup lang="ts">
import { useZoom, ZoomMode } from '@embedpdf/plugin-zoom/vue';

const { state: zoomState, provides: zoomProvider } = useZoom();

const handleZoomIn = () => {
  zoomProvider.value?.zoomIn();
};
</script>

<template>
  <v-btn @click="handleZoomIn" icon="mdi-plus-circle-outline" />
  <v-menu>
    </v-menu>
</template>
```

### 3\. Responsive Design

The example uses Vuetify's built-in responsive utilities (`useDisplay`) to adapt the layout for smaller screens. On mobile, sidebars (`VNavigationDrawer`) automatically collapse into a `VBottomSheet`, and some toolbar icons are hidden to save space, providing a more native-like experience. This logic is managed by a custom `drawer-system`.

## Running the Example Locally

You can run the full Vuetify example on your machine to experiment with the code.

> **Prerequisites:** You'll need Node.js 18+ and pnpm.

### 1\. Clone the repository:

```bash
git clone https://github.com/embedpdf/embed-pdf-viewer.git
cd embed-pdf-viewer
```

### 2\. Install dependencies:

```bash
pnpm install
```

### 3\. Build the core packages

The example imports the core EmbedPDF packages from the local workspace. You need to build them once.

```bash
pnpm run build --filter "./packages/*"
```

### 4\. Run the example's dev server:

```bash
pnpm --filter @embedpdf/example-vue-vuetify run dev
```

Vite will start the development server, and you can access the viewer at `http://localhost:3000`.